/*
 *    Copyright (c) 2018-2025, lengleng All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the pig4cloud.com developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: lengleng (wangiegie@gmail.com)
 */
package com.pig4cloud.pig.myvideos.service.impl;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.text.UnicodeUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pig.myvideos.entity.Myvideos;
import com.pig4cloud.pig.myvideos.mapper.MyvideosMapper;
import com.pig4cloud.pig.myvideos.service.MyvideosService;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * 视频管理
 *
 * @author pig code generator
 * @date 2021-12-09 15:18:26
 */
@Service
public class MyvideosServiceImpl extends ServiceImpl<MyvideosMapper, Myvideos> implements MyvideosService {

	public static final String path_python = "J:\\_ALL\\CODE\\venv\\py386_automate\\Scripts\\python.exe";
	public static final String path_script_fabu_shipinhao = "J:\\_ALL\\CODE\\gitee\\constellations\\pig\\pig-yeahmao\\myvideos_tools\\src\\fabu_shipinhao.py";
	public static final String path_script_fabu_douyin = "J:\\_ALL\\CODE\\gitee\\constellations\\pig\\pig-yeahmao\\myvideos_tools\\src\\fabu_douyin.py";
	public static final String path_script_crawl_video = "D:\\_ALL\\CODE\\gitee\\constellations\\Capricorn\\WeChat\\爬虫\\tiktok\\src\\视频下载重命名-tiktok.py";
	public static final String path_script_android2pc = "D:\\_ALL\\CODE\\gitee\\constellations\\Capricorn\\WeChat\\爬虫\\tiktok\\src\\视频拷至PC-tiktok.py";

	//读取json文件
	public static String readJsonFile(String fileName) {
		String jsonStr = "";
		try {
			File jsonFile = new File(fileName);
			FileReader fileReader = new FileReader(jsonFile);
			Reader reader = new InputStreamReader(new FileInputStream(jsonFile),"utf-8");
			int ch = 0;
			StringBuffer sb = new StringBuffer();
			while ((ch = reader.read()) != -1) {
				sb.append((char) ch);
			}
			fileReader.close();
			reader.close();
			jsonStr = sb.toString();
			return jsonStr;
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}
	}

	public static String readJsonFile(MultipartFile files) {
		String jsonStr = "";
		try {
			//起手转成字符流
			InputStream is = files.getInputStream();
			InputStreamReader reader = new InputStreamReader(is, StandardCharsets.UTF_8);
			int ch = 0;
			StringBuffer sb = new StringBuffer();
			while ((ch = reader.read()) != -1) {
				sb.append((char) ch);
			}
			reader.close();
			jsonStr = sb.toString();
			return jsonStr;
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}
	}

	public static Integer convertBoolean2Interger(Object obj) {
		return (Boolean)obj?1:0;
	}

	// Controller的接口
	public boolean saveAll(MultipartFile files, String myVideoClass, String myTagsCn) {
		// 读取本地文件（json）
		// String fileName = "J:\\_ALL\\CODE\\gitee\\constellations\\Capricorn\\WeChat\\爬虫\\tiktok\\data\\2021-12-10--6307840-gmail.json";
//		String fileName = "J:\\_ALL\\CODE\\gitee\\constellations\\Capricorn\\WeChat\\爬虫\\tiktok\\data\\2021-12-10--kinghz-gmail.json";
//		String s = readJsonFile(fileName);
		String s = readJsonFile(files);
		return saveAll(s, myVideoClass, myTagsCn);
	}

	// 测试的接口
	public boolean saveAll(String s, String myVideoClass, String myTagsCn) {
		// 文件解析入库
		JSONObject jobj = JSON.parseObject(s);
		Integer statusCode = jobj.getInteger("statusCode");
		System.out.println("statusCode = " + statusCode);

		List<Myvideos> myvideosList = new ArrayList<Myvideos>();
		JSONArray itemList = jobj.getJSONArray("itemList");//构建JSONArray数组
		for (int i = 0; i < itemList.size(); i++){
			JSONObject item = (JSONObject)itemList.get(i);
			String _id = (String)item.get("id");
			System.out.println("_id = " + _id);
//            String desc = (String)item.get("desc");
//            System.out.println("desc = " + desc);

			QueryWrapper<Myvideos> queryWrapper = new QueryWrapper<>();
			Map<String,Object> map = new HashMap<>();
			map.put("j_id",_id);
			queryWrapper.allEq(map, false);
			List<Myvideos> video = this.list(queryWrapper);
			// 判断数据库中是否包含_id对应的数据
			if (video.size() >= 1) {
				System.out.println("【已经存在该视频】 ： " + _id);
				continue;
			}

			// 将json对象中的数据，保存在Myvideos对象中
			Myvideos myvideos_new = new Myvideos();
			// 设置参数
			myvideos_new.setMyVideoClass(myVideoClass);
			myvideos_new.setMyTagsCn(myTagsCn);
			// 设置基础数据
			myvideos_new.setJId(_id);
			myvideos_new.setJDesc((String)item.get("desc"));
			myvideos_new.setJCreatetime((Integer) item.get("createTime"));

			// 解析video元素
			JSONObject item_video = item.getJSONObject("video");
			myvideos_new.setVideoId((String)item_video.get("id"));
			myvideos_new.setVideoHeight((Integer) item_video.get("height"));
			myvideos_new.setVideoWidth((Integer) item_video.get("width"));
			myvideos_new.setVideoDuration((Integer) item_video.get("duration"));
			myvideos_new.setVideoRatio((String) item_video.get("ratio"));
			myvideos_new.setVideoCover((String) item_video.get("cover"));
			myvideos_new.setVideoCover((String) item_video.get("originCover"));
			myvideos_new.setVideoDynamiccover((String) item_video.get("dynamicCover"));
			myvideos_new.setVideoPlayaddr((String) item_video.get("playAddr"));
			myvideos_new.setVideoDownloadaddr((String) item_video.get("downloadAddr"));
			myvideos_new.setVideoReflowcover((String) item_video.get("reflowCover"));
			myvideos_new.setVideoBitrate((Integer) item_video.get("bitrate"));
			myvideos_new.setVideoEncodedtype((String) item_video.get("encodedType"));
			myvideos_new.setVideoFormat((String) item_video.get("format"));
			myvideos_new.setVideoVideoquality((String) item_video.get("videoQuality"));
			myvideos_new.setVideoEncodeusertag((String) item_video.get("encodeUserTag"));
			myvideos_new.setVideoCodectype((String) item_video.get("codecType"));
			myvideos_new.setVideoDefinition((String) item_video.get("definition"));

			// 解析stats元素
			JSONObject item_stats = item.getJSONObject("stats");
			myvideos_new.setStatsDiggcount((Integer) item_stats.get("diggCount"));
			myvideos_new.setStatsSharecount((Integer) item_stats.get("shareCount"));
			myvideos_new.setStatsCommentcount((Integer) item_stats.get("commentCount"));
			myvideos_new.setStatsPlaycount((Integer) item_stats.get("playCount"));

			// 解析author元素
			JSONObject item_author = item.getJSONObject("author");
			myvideos_new.setAuthorId((String) item_author.get("id"));
			myvideos_new.setAuthorUniqueid((String) item_author.get("uniqueId"));
			myvideos_new.setAuthorNickname((String) item_author.get("nickname"));
			// "avatarThumb":"https://p16-sign-va.tiktokcdn.com/tos-maliva-avt-0068/6400086fa0fed6873b96b24bd925ad5a~c5_100x100.jpeg?x-expires=1637751600\u0026x-signature=3pKhW6bvDYCjxXFU%2Bp9Lx5g6SSU%3D"
			// ==>     tos-maliva-avt-0068/6400086fa0fed6873b96b24bd925ad5a
			String avatarThumb = (String)item_author.get("avatarThumb");
			if (!avatarThumb.isEmpty()) {
				String[] _ = avatarThumb.split("~c5_");
				if (_.length == 2) {
					avatarThumb = _[0];
				} else {
					String[] __ = avatarThumb.split(".jpeg?");
					if (__.length == 2) {
						avatarThumb = __[0];
					} else {
						throw new ArithmeticException();
					}
				}
			}
			System.out.println("avatarThumb = " + avatarThumb);
			String[] lst_avatarThumb = avatarThumb.split("/");
			avatarThumb = lst_avatarThumb[lst_avatarThumb.length-2] + "/" + lst_avatarThumb[lst_avatarThumb.length-1];
			myvideos_new.setAuthorAvatarthumb(avatarThumb);
			myvideos_new.setAuthorAvatarmedium((String) item_author.get("avatarMedium"));
			myvideos_new.setAuthorAvatarlarger((String) item_author.get("avatarLarger"));
			myvideos_new.setAuthorSignature((String) item_author.get("signature"));
			myvideos_new.setAuthorVerified((Integer) convertBoolean2Interger(item_author.get("verified")));
			myvideos_new.setAuthorSecuid((String) item_author.get("secUid"));
			myvideos_new.setAuthorSecret((Integer) convertBoolean2Interger(item_author.get("secret")));
			myvideos_new.setAuthorFtc((Integer) convertBoolean2Interger(item_author.get("ftc")));
			myvideos_new.setAuthorRelation((Integer) item_author.get("relation"));
			myvideos_new.setAuthorOpenfavorite((Integer) convertBoolean2Interger(item_author.get("openFavorite")));
			myvideos_new.setAuthorCommentsetting((Integer) item_author.get("commentSetting"));
			myvideos_new.setAuthorDuetsetting((Integer) item_author.get("duetSetting"));
			myvideos_new.setAuthorStitchsetting((Integer) item_author.get("stitchSetting"));
			myvideos_new.setAuthorPrivateaccount((Integer) convertBoolean2Interger(item_author.get("privateAccount")));

			// 解析authorStats元素
			JSONObject item_authorStats = item.getJSONObject("authorStats");
			myvideos_new.setAuthorstatsFollowercount((Integer) item_authorStats.get("followingCount"));
			myvideos_new.setAuthorstatsHeartcount((Integer) item_authorStats.get("heartCount"));
			myvideos_new.setAuthorstatsVideocount((Integer) item_authorStats.get("videoCount"));
			myvideos_new.setAuthorstatsDiggcount((Integer) item_authorStats.get("diggCount"));
			myvideos_new.setAuthorstatsHeart((Integer) item_authorStats.get("heart"));

			// 其他自定义的字段
			myvideos_new.setCreateBy("MyvideosServiceImpl");

			myvideosList.add(myvideos_new);
			System.out.println("【视频入库】 ： " + _id);
		}

		return this.saveBatch(myvideosList);
	}

	public boolean FabuCommon(String jId, String path_script) {
		// 获取元素
		QueryWrapper<Myvideos> queryWrapper = new QueryWrapper<>();
		Map<String,Object> map = new HashMap<>();
		map.put("j_id", jId);
		queryWrapper.allEq(map, false);
		List<Myvideos> video = this.list(queryWrapper);
		// 判断数据库中是否包含_id对应的数据
		if (video.size() == 0) {
			System.out.println("【未找到该视频】 ： " + jId);
			return false;
		}

		Myvideos v = video.get(0);
		if (v.getMyTitleCn().isEmpty() || v.getMyTagsCn().isEmpty()) {
			System.out.println("【视频标题或者标签不能为空】 ： " + jId);
			return false;
		}
		if (path_script == path_script_fabu_shipinhao) {
			if (v.getMyFlagShipinhao() == 1) {
				System.out.println("【视频已经发布过了】 ： " + jId);
				return true;
			}
		}
		else if (path_script == path_script_fabu_douyin) {
			if (v.getMyFlagDouyin() == 1) {
				System.out.println("【视频已经发布过了】 ： " + jId);
				return true;
			}
		} else {
			System.out.println("【参数错误】 path_script： " + path_script);
			return false;
		}

		boolean ret = FabuCommon(jId, v.getMyTitleCn(), v.getMyTagsCn(), path_script);
		// 标记已经发送
		if (ret) {
			if (path_script == path_script_fabu_shipinhao) {
				v.setMyFlagShipinhao(1);
			}
			else if (path_script == path_script_fabu_douyin) {
				v.setMyFlagDouyin(1);
			}
			this.updateById(v);
		}

		return true;
	}

	@Override
	public boolean FabuShipinhao(String jId) {
		return FabuCommon(jId, path_script_fabu_shipinhao);
	}

	public boolean FabuCommon(String jId, String myTitleCn, String myTagsCn, String path_script) {
		SortedMap<String, String> sortedMap = new TreeMap<String, String>();
		sortedMap.put("jId", jId);
		sortedMap.put("myTitleCn", myTitleCn);
		sortedMap.put("myTagsCn", myTagsCn);
		String j = JSONUtil.toJsonStr(sortedMap);
		j = UnicodeUtil.toUnicode(j);
		System.out.println(j);

		// Base64
		String encode = Base64.encode(j);
		System.out.println(encode);

		// 执行任务
		boolean ret = false;
		String cmd = StrUtil.format("{} {} {}", path_python, path_script, encode);
		System.out.println(cmd);
		Process pro = null;
		try {
			pro = Runtime.getRuntime().exec(cmd);
			int exitVal = 0;
			if( pro.waitFor(2 * 60, TimeUnit.SECONDS) ) {
				exitVal = pro.exitValue();
				System.out.println(exitVal);

				ret = (exitVal == 0);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

		return ret;
	}

	@Override
	public boolean FabuShipinhao(String jId, String myTitleCn, String myTagsCn) {
		return FabuCommon(jId, myTitleCn, myTagsCn, path_script_fabu_shipinhao);
	}

	@Override
	public boolean FabuDouyin(String jId) {
		return FabuCommon(jId, path_script_fabu_douyin);
	}

	@Override
	public boolean crawlVideo() {
		List<Myvideos> list = this.list();
		String ids = "";
		for (Myvideos video : list) {
			ids += video.getJId() + ",";
		}

		boolean ret = false;
		String cmd = StrUtil.format("cmd /k  start  {} {} {}", path_python, path_script_crawl_video, ids);
		System.out.println(cmd);
		Process pro = null;
		try {
			pro = Runtime.getRuntime().exec(cmd);
			int exitVal = 0;
			if( pro.waitFor(2 * 60, TimeUnit.SECONDS) ) {
				exitVal = pro.exitValue();
				System.out.println(exitVal);

				ret = (exitVal == 0);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

		return ret;
	}

	@Override
	public boolean android2pc() {
		boolean ret = false;
		String cmd = StrUtil.format("cmd /k  start  {} {}", path_python, path_script_android2pc);
		System.out.println(cmd);
		Process pro = null;
		try {
			pro = Runtime.getRuntime().exec(cmd);
			int exitVal = 0;
			if( pro.waitFor(2 * 60, TimeUnit.SECONDS) ) {
				exitVal = pro.exitValue();
				System.out.println(exitVal);

				ret = (exitVal == 0);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

		return ret;
	}
}
